#!/usr/bin/perl -w

# This is admin.pl, part of Picture Bank.  admin.pl sets up and maintains
#+ a "map" file listing all the directories of interest.  It also parses 
#+ out searchable terms and keywords from an existing map file.  You should
#+ always start using Picture Bank starting from admin.pl.
# See the files README, LICENCE and Changelog for more info.

# Copyright (C) 2007 Alexis Phoenix

# url is something like
# admin.pl?map=test.map
# admin.pl?name=name&root=/root/of/files
# admin.pl?update=test.map

# 30/5/07 removed last bits of commented out code

use CGI;
use CGI::Pretty;
$query=CGI->new();
$map=$query->param("map");
$name=$query->param("name");
$root=$query->param("root");
$update=$query->param("update");
#$ME=$query->script_name();
$ME="admin.pl";
$EDIT="edit.pl";
$SEARCH="search.pl";
$THUMBS="thumbs.pl";
#print "this is me ". "$ME";
$config_path="/usr/lib/cgi-bin/config/";
#$config_path="/home/alexis/picture-bank/config/";
#$mapname='.map';

print $query->header(),
      $query->start_html(-title=>'Picture Bank',lang=>'en-GB'),
      $query->h3('Perform Admin Tasks.  Start here'),
      $query->hr({-width=>'80%', align=>'center'});

if ( defined $map ) {

print "You chose: "."$map ",
      $query->a({href=>"$EDIT?map=$map"},'Edit this file'),
      $query->a({href=>"$ME?update=$map"},'Update this file');

  gals_and_terms();
  addmap();
}

elsif (defined $update) {
  update("$config_path","$update")
}

elsif (defined $name && ! defined $root || 
defined $root && ! defined $name) {
  cant_create_map()
}

elsif (defined $name && defined $root) {
  newmap($name) or die "Can't run newmap"
}

else {
  chooser();
}

print $query->p(
                $query->a({href=>"$ME"},'Reload admin section from start')
               ),
      $query->end_html;
print "\n"; # for when testing in a terminal

sub addmap {
if (scalar(@_)>0) {
  $mapname=$_[0];
}
else {
  $mapname=".map"
}

print $query->start_form(-method=>"post",action=>"$ME"),
      $query->table({-border=>"0"},
                    $query->caption('You may add a new map here:'),"\n",
                    $query->Tr({align=>"left",valign=>"top"},
                    [
                    $query->td(['The name of the new map',$query->textfield(-name=>"name",value=>$mapname)]),
                    $query->td(['The root directory <br>(without a trailing slash)',$query->textfield(-name=>"root")]),
                    $query->td({align=>"right"},$query->submit(-name=>"submit",value=>"create"),$query->reset())
                    ])
                   ),
      $query->end_form;

} #end of addmap

sub chooser {
  opendir (CONF, $config_path);
  my @files=readdir(CONF);
  foreach (@files) {
    if (m/.\.map$/) {
      push (@maps, $_)
    }
  }
    if (defined @maps) {
    if ($#maps==0) {
      print "Found 1 album: $maps[0] \n";
      $map=$maps[0];
      print $query->a({href=>"$EDIT?map=$map"},'Edit this file'),
            $query->a({href=>"$ME?update=$map"},'Update this file');
      gals_and_terms();
      addmap();
    }
    elsif ($#maps > 0) {
      print $query->p("Found ".($#maps+1)." maps<br>Choose a map below");
      
      foreach (@maps) {
              $_ = $query->a({href=>"$ME?map=$_"},$_).
              ' Options: '.
              $query->a({href=>"$EDIT?map=$_"},'Edit this file').
              $query->a({href=>"$ME?update=$_"},'Update this file')
      }
      print $query->ul(
            $query->li([@maps])
            );
       addmap()
    } 
    } ## completes if defined
    else {
      print "No maps found.  Start a new album\n";
      addmap()
    }
}

sub gals_and_terms {
 open (MAP, "$config_path$map") or die "could not open map";
  while (<MAP>) {
    push (@maplines, $_);
    if (/(:gallery\S+)/) {
      @name=split("-",$1);
      @bits=split(" ",$_);
      @element=($name[1],$bits[0]); ## the name after "gallery", and the path
      push @gallery, [@element];
    }  #end if
  }  # end while
  @gallery=sort (@gallery);
  if (scalar(@gallery)>0) {
    print $query->h4('Gallery List');
    $n=$p=0;
    my $seen=$gallery[0][0];
    print $query->p("Gallery: $gallery[0][0]");
    while ($n <= $#gallery) {
      $listitems[$n]=$query->a({href=>"$THUMBS?gallery=$gallery[$n][1]"},"$gallery[$n][1]");
      unless ($seen eq $gallery[$n][0]) {
        print $query->ul(
              $query->li({-type=>'disc'},[@listitems[$p..$n-1]])
                        );
        print $query->p("Gallery: $gallery[$n][0]");
        $seen=$gallery[$n][0];
        $p=$n
      } # end unless
      $n++;
      if ($n>$#gallery) {
        local $n=$n-1;
        print $query->ul(
              $query->li({-type=>'disc'},[@listitems[$p..$n]])
                        )
      }
    } # end while
  }  # end if
# end of galleries extraction
  print $query->p('quick search');
  foreach (@maplines) {
    unless (/:ignore/||/:new/) {
      my $line=$_;
      @bits=split(" ", "$line");
      shift(@bits);
      foreach(@bits){
        unless (exists($terms{$_})||m/:gallery\S+/) {
          $terms{$_}=1;
          print $query->p(
                $query->a({href=>"$SEARCH?map=$map&terms=$_"},$_))
        } #end unless
      } #end foreach
    } #end unless
  } #end foreach
  if (keys(%terms)==0) {
    print $query->p('No search terms available')
  }

close(MAP)
}# end sub

sub cant_create_map {
  print $query->h2('Failed attempt to create album!'),
        $query->p('You need to provide both a root directory and a name for this album, or specify an existing collection to browse');
  chooser()
}

sub newmap {
  $map_name="$config_path".shift(@_);
  if ($map_name!~/\.map/) { # ensure there is a .map extension
    $map_name="$map_name".".map"
  }
  open (MAP, ">$map_name") or die "can't open file $map_name";
  buildmap ($root);
    foreach $l (sort keys(%map)) {
    $l=~tr/ /\+/;  # swap spaces for plusses or it won't work properly.
    print MAP "$l :new"."\n" or die "can't create map";
  }  
  close (MAP);
  print $query->p('Created new directory listing, ',
        $query->em($name),
        ' from the root directory, ',
        $query->em($root)),
        $query->p("You should now edit this listing and put in searchable terms and keywords (keywords always begin ".
                  "with a colon, and tell Picture Bank to behave in certain ways).  Click the link to edit $name<br>",
        $query->a({href=>"$EDIT?map=$name"},"Edit $name"))
}

sub buildmap {
  my $path=shift(@_);
  $path=~tr/\+/ /;   # in case plusses were put in to fill any spaces
  opendir (DIR, $path);
  my $flag=0;
  my @files=readdir(DIR);
  foreach (@files) {
    unless (m/^\./) {   # skip any that start with a dot - ie are hidden (*nix only)
      my $canonical="$path/$_";
      if (!-d $canonical) {  # ensures empty directories aren't included
        unless ($flag==1) {  #+ could do with something to allow inclusion.
          $flag=1;
          $map{$path}=1;  # use a hash to ensure no duplicates
        }
      }
      elsif (-d $canonical) {
        buildmap ($canonical)  # if a directory is found, run the sub on it
      }
    }
  }
  closedir(DIR)
}

sub update {
my $file=$update=pop @_;
my $path=pop @_;
$update="$path"."$update";
  open(OLD, "$update") or die "can't open old, @_";
  foreach (<OLD>) {
    print "original file: $_<br>";
    push (@oldfile, $_);
  }
  close(OLD);
  if (scalar(@oldfile)>0) {
    @root=split(" ",$oldfile[0])
  } 
  else {
    print $query->p("Map file $update appears to be empty.  Please use the function below to create entries");
    &addmap($file);
    return
  }
  chomp $root[0];
  print "Root of directory of album is $root[0]<br>\n";
  buildmap($root[0]);
  LOOP: foreach $row (@oldfile) {  ## deal with everything in oldfile first
          chomp $row;
          foreach $line (keys(%map)) {
            if ($row=~/^$line/) {  ## check syntax - what's being matched here?
              push (@lines, $row);  ## if it exists, keep it
              delete $map{$line};   ## delete from map hash now we've saved it
              
              next LOOP  ## skip the rest of the map hash
            }
          }
        }
foreach (keys %map) {
  tr/ /\+/;  # swap spaces for plusses or it won't work properly.
  print "New directory: $_<br>\n";  ## later add code to allow editing of line
  push (@lines, "$_ :new")  # what's left must be new
}
@lines=sort(@lines);
rename ($update, "$update\.old");
open (MAP, ">$update") or print "can't open update $update";
foreach $l (@lines) {
#  $l=~tr/ /\+/;  # swap spaces for plusses or it won't work properly.
 # print "$l <br>\n";
  print MAP "$l"."\n"
}
close (MAP);
print $query->p("Finished updating $update.<br>Original file renamed to $update.old"),
      $query->p("Now go to ",
      $query->a({href=>"$EDIT?map=$file"},'Edit my map file'));
}


